home *** CD-ROM | disk | FTP | other *** search
- /*
- * os9rec.c receive file routines for os9 kermit
- */
-
- #include "os9inc.h"
-
- /*
- * r e c s w
- *
- * This is the state table switcher for receiving files.
- */
-
- recsw()
- {
- char rinit(), rfile(), rdata(); /* Use these procedures */
-
- state = 'R'; /* Receive-Init is the start state */
- n = 0; /* Initialize message number */
- numtry = 0; /* Say no tries yet */
-
- /*
- * We are commenting out code that automatically NAKed
- * in case the sender started first; this may be the reason
- * that this Kermit gets out of whack. The original code
- * said
- * if (gflg == FALSE)
- * spack('N', n, 0, 0);
- */
-
- for (;;) {
- if (debug)
- printf(" recsw state: %c\n",state);
- switch(state) { /* Do until done */
- case 'R':
- state = rinit(); break; /* Receive-Init */
- case 'F':
- state = rfile(); break; /* Receive-File */
- case 'D':
- state = rdata(); break; /* Receive-Data */
- case 'C':
- return(TRUE); /* Complete state */
- case 'A':
- return(FALSE); /* "Abort" state */
- }
- }
- }
-
- /*
- * r i n i t
- *
- * Receive Initialization
- */
-
- char rinit()
- {
- int len, num; /* Packet length, number */
- char sfile(); /* routine used for get command */
-
- if (numtry++ > MAXTRY)
- return('A'); /* If too many tries, "abort" */
-
- switch(rpack(&len, &num, packet)) { /* Get a packet */
- case 'S': /* Send-Init */
- rpar(packet); /* Get the other side's init data */
- spar(packet); /* Fill up packet with my init info */
- spack('Y', n, 6, packet); /* ACK with my parameters */
- oldtry = numtry; /* Save old try count */
- numtry = 0; /* Start a new counter */
- n = (n + 1) % 64; /* Bump packet number, mod 64 */
- return('F'); /* Enter File-Receive state */
-
- case 'E': /* Error packet received */
- prerrpkt(packet); /* Print it out and */
- return('A'); /* abort */
-
- case FALSE: /* Didn't get packet */
- case 'N': /* or got a NAK */
- if (gflg)
- sfile(); /* request file again */
- else
- spack('N', n, 0, 0); /* Return a NAK */
- return(state); /* Keep trying */
-
- case 'Y':
- return(state); /* Ignore leftover ACK */
- /* (or incorrect ACK of 'R' packet) */
-
- default:
- return('A'); /* Some other packet type, "abort" */
- }
- }
-
- /*
- * r f i l e
- *
- * Receive File Header
- */
-
- char rfile()
- {
- int num, len; /* Packet number, length */
- char filnam1[50]; /* Holds the converted file name */
-
- if (numtry++ > MAXTRY)
- return('A'); /* "abort" if too many tries */
-
- switch (rpack(&len, &num, packet)) { /* Get a packet */
- case 'S': /* Send-Init, maybe our ACK lost */
- if (oldtry++ > MAXTRY)
- return('A'); /* If too many tries "abort" */
- if (num != ((n == 0) ? 63 : n - 1))
- return('A'); /* Not previous packet, "abort" */
- /* Previous packet, mod 64; ack with our */
- /* Send-Init parameters */
- spar(packet);
- spack('Y', num, 6, packet);
- numtry = 0; /* Reset try counter */
- return(state); /* Stay in this state */
-
- case 'Z': /* End-Of-File */
- if (oldtry++ > MAXTRY)
- return('A');
- if (num != ((n==0) ? 63:n-1))
- return('A'); /* Not previous packet, "abort" */
- spack('Y',num,0,0);
- numtry = 0;
- return(state); /* Stay in this state */
-
- case 'F': /* File Header (just what we want) */
- if (num != n)
- return('A'); /* The packet number must be right */
- strcpy(filnam1, packet); /* Copy the file name */
-
- if (filnamcnv) { /* Convert upper case to lower */
- for (filnam = filnam1; *filnam != '\0'; filnam++)
- if (*filnam >= 'A' && *filnam <= 'Z')
- *filnam |= 040;
- }
-
- /* Try to open a new file */
-
- if ((fp = fopen(filnam1, "w")) == NULL) {
- error("Cannot create %s", filnam1);
- return('A'); /* Give up */
- }
-
- /* OK, give message */
- printmsg("Receiving %s as %s", packet, filnam1);
-
- spack('Y', n, 0, 0); /* Acknowledge the file header */
- oldtry = numtry; /* Reset try counters */
- numtry = 0; /* ... */
- n = (n + 1) % 64; /* Bump packet number, mod 64 */
- return('D'); /* Switch to Data state */
-
- case 'B': /* Break transmission (EOT) */
- if (num != n)
- return ('A'); /* Need right packet number here */
- spack('Y', n, 0, 0); /* Say OK */
- return('C'); /* Go to complete state */
-
- case 'E': /* Error packet received */
- prerrpkt(packet); /* Print it out and */
- return('A'); /* abort */
-
- case FALSE: /* Didn't get packet */
- spack('N', n, 0, 0); /* Return a NAK */
- return(state); /* Keep trying */
-
- default:
- return ('A'); /* Some other packet, "abort" */
- }
- }
-
- /*
- * r d a t a
- *
- * Receive Data
- */
-
- char rdata()
- {
- int num, len; /* Packet number, length */
-
- if (numtry++ > MAXTRY)
- return('A'); /* "abort" if too many tries */
-
- switch (rpack(&len, &num, packet)) { /* Get packet */
- case 'D': /* Got Data packet */
- if (num != n) { /* Right packet? */
- /* No! */
- if (oldtry++ > MAXTRY || /* too many tries */
- (num != ((n==0) ? 63:n-1))) /* not prev. packet */
- return('A');
- spack('Y', num, 6, packet); /* Yes, re-ACK it */
- numtry = 0; /* Reset try counter */
- return(state); /* Don't write data! */
- }
- /* Got data with right packet number */
- #ifdef nooverlap
- /* Cannot handle concurrent disk and serial i/o, so delay ACK */
- /* until file written */
- bufemp(packet, len); /* Write the data to the file */
- spack('Y', n, 0, 0); /* Acknowledge the packet */
- #else
- /* ACK before file write to overlap disk and serial i/o */
- spack('Y', n, 0, 0); /* Acknowledge the packet */
- bufemp(packet, len); /* Write the data to the file */
- #endif
- oldtry = numtry; /* Reset the try counters */
- numtry = 0; /* ... */
- n = (n + 1) % 64; /* Bump packet number, mod 64 */
- return('D'); /* Remain in data state */
-
- case 'F': /* Got a File Header */
- if (oldtry++ > MAXTRY || /* too many tries */
- (num != ((n==0) ? 63:n-1))) /* not prev. packet */
- return('A');
- spack('Y', num, 0, 0); /* ACK it again */
- numtry = 0; /* Reset try counter */
- return(state); /* Stay in Data state */
-
- case 'Z': /* End-Of-File */
- if (num != n)
- return('A'); /* Must have right packet number */
- #ifdef nooverlap
- /* can't handle disk and serial i/o at the same time */
- fclose(fp); /* close the file */
- spack('Y', n, 0, 0); /* Ack the 'Z' packet */
- #else
- /* ACK before close to allow i/o overlap */
- spack('Y', n, 0, 0); /* OK, ACK it. */
- fclose(fp); /* Close the file */
- #endif
- n = (n + 1) % 64; /* Bump packet number */
- return('F'); /* Go back to Receive File state */
-
- case 'E': /* Error packet received */
- prerrpkt(packet); /* Print it out and */
- return('A'); /* abort */
-
- case FALSE: /* Didn't get packet */
- spack('N', n, 0, 0); /* Return a NAK */
- return(state); /* Keep trying */
-
- default:
- return('A'); /* Some other packet, "abort" */
- }
- }
-